Creating executable software code typically involves a software developer first creating a source code program with a text processing program, followed by compiling and linking the source code to create executable code for a specified computer processor. The executable code is subsequently stored in an executable file. The executable code can then be debugged by the software developer by executing the executable file on the specified computer processor to determine if the software performs its tasks correctly, or if instead one or more errors occur during execution. If the executable code has errors, the software developer can modify the source code in an attempt to remove the errors, recompile the source code, and then link the recompiled code to produce a new executable file for debugging. For large software programs, this process is repeated several times until all known errors are removed.
The debugging process, which is quite often a very involved process, many times requires the software developer to locate the cause of an error from executing the executable file. Various methods exist for a software developer to identify errors. In one such method, a software developer adds print statements throughout the source code so that as the executable file is executing, the corresponding executable print instructions are also executed to report the current progress of the execution. Knowledge of the current execution progress assists the software developer to identify the section of the code that is executing when an error occurs. Additionally, print statements can be used to also display the current value of variables or source code expressions at specified points throughout the execution. Since the print statements are part of the original compilation and linking process, the variables and expressions that are part of the print statements are evaluated in the context of the current variable scope, as would any other compiled code statement. An example of this is using the value of a local variable in a currently executing function rather than a variable with the same name in a different non-executing function.
In addition to print requests, application programs known as debuggers may be also used by the software developer to assist with locating errors in the executable code. A debugger loads executable code into memory and provides additional control over execution of executable files. For example, the software developer can use the debugger to execute one executable code instruction at a time. Alternately, the debugger may be used to execute the executable code continuously until a break point, designated by the software developer within the debugger, is reached. When execution of the executable code is stopped, a user can interact with the debugger to view current values of variables and expressions. Some debuggers can also reconstruct the source code from information stored in an executable code file during the compiling and linking steps, and display the source code lines that correspond to the instructions in the executable code. The display of the source code facilitates control by the software developer of the execution of the executable code.
Software developers debugging source code written for embedded systems face particular challenges when trying to analyze the performance of the software. An embedded system may be characterized as one whose primary purpose is to perform a specific function rather than to perform general computational functions. A microprocessor-based microwave oven controller, a microprocessor-based automobile ignition system, and a microprocessor-based telephone switching system are all examples of embedded systems. The techniques of debugging software discussed above are not easily applied to software written for embedded systems. One reason is that many embedded systems include only a central processor and limited memory, and do not include access to other standard computer system input or output devices, such as a keyboard or display. As such, it is often difficult for a software developer to debug or analyze the performance of software written for these types of systems using the conventional techniques. However, fortunately for the software developer, there are several alternative techniques, and software analysis equipment, that are more suited for analyzing software written for and executed in these types of systems.
One such technique uses executable code marker statements inserting into spaces created in the source code during compilation. That is, the source code is prepared for debugging by compiling the source code and inserting empty spaces following each function of the source code. The empty spaces are reserved for inserting the code markers during an analysis phase by the software developer after the source code has been compiled and linked. The inserted code markers are captured by a debugging system during the execution of the modified compiled source code, and the results from the collection of code markers are used as a means of determining the performance of the software program. For example, each tag statement may write a value to a respective address so that the identity of the address containing that value provides an indication of which tag statements were executed. The data is collected by the host system and displayed in a manner that assists the software developer with debugging and evaluating the performance of the software. A more detailed description of this technique and analysis system is provided by U.S. Pat. No. 5,265,254, to Blasciak et al.
Another technique and analysis system employs a host system coupled to the microprocessor of an embedded system. Executable tag statements inserted into a source code are executed along with the compiled and linked source code. Each of the tag statements cause the microprocessor to write a tag to a predetermined address location in a memory of the embedded system. A probe coupled to the external terminals of the embedded system monitors an address bus for the predetermined address, and when detected, latches data provided by an executed tag statement from a data bus. Based on the value of the data latched, the analysis system is able to determine the location in the source code being executed. A more detailed description of this technique and analysis system is provided by U.S. Pat. No. 5,748,878, to Rees et al.
Although the aforementioned techniques and analysis systems provide the software developer with powerful tools for debugging and evaluating the software for embedded systems, it is difficult in these systems to modify the type of data collected during the execution of the instrumented source code. These systems typically allow the software developer to manually insert a limited number of executable statements into the executable code after compilation and linking. However, where the modifications to the executable statements are extensive, or the source code is long, such a technique is inefficient and impractical. Thus, adding or deleting executable statements from the executable code often requires the software developer to instrument, compile, and link the source code each time changes are made.